/*
 * Copyright 2006-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package asphalt2.validator.util
{
	import flash.display.DisplayObject;
	import flash.net.getClassByAlias;
	
	import mx.controls.ComboBase;
	import mx.controls.ComboBox;
	import mx.controls.DateField;
	import mx.core.Container;
	import mx.core.UIComponent;
	import mx.core.mx_internal;
	
	use namespace mx_internal;
	/**
	 * エラーチェック用ユーティリティ
	 * @author c9katayama
	 **/
	public class ValidatorUtils
	{
		
		public static var ERROR_COLOR_STYLE_NAME:String = "errorColor";
		
		public static var ERROR_BG_COLOR_STYLE_NAME:String = "errorBackgroundColor";
		
		public static var BG_COLOR_STYLE_NAME:String = "backgroundColor";
		
		public static var FILL_COLOR_STYLE_NAME:String = "fillColors";
		
		public static var HOLD_BG_COLOR_STYLE_NAME:String = "__backgroundColor";
		
		private static var NULL_BG_COLOR:String = "NULL_BG_COLOR";
		
		/**
		 * UIComponentに対して、エラーメッセージをセットします。
		 * エラー発生時、枠だけでなく背景もエラー色にします。 
		 * エラー時の枠の色はerror-color(errorColor)、
		 * エラー時の背景はerror-background-color(errorBackgroundColor)
		 * で定義します。
		 * エラー時の背景は、error-background-colorでスタイル定義していない場合、
		 * error-colorを使用します。
		 **/
		public static function setUIError(comp:UIComponent,msg:String):void{
			comp = stripComponent(comp);
			//元の背景色を保存
			var bgStyleName:String = getColorStyleName(comp); 
			var baseBgColor:Object = comp.getStyle(bgStyleName);
			if(baseBgColor == null){
				baseBgColor = NULL_BG_COLOR;
			}
			comp.setStyle(HOLD_BG_COLOR_STYLE_NAME,baseBgColor);

			var errorStyle:Object = comp.getStyle(ERROR_BG_COLOR_STYLE_NAME);
			if(errorStyle==null){
				errorStyle = comp.getStyle(ERROR_COLOR_STYLE_NAME);
			}
			if(errorStyle != null){
				if(isFillColorsComponent(comp)){
					errorStyle = [errorStyle,errorStyle];
				}			
				comp.setStyle(bgStyleName,errorStyle);
			}
			comp.errorString = msg;
		}
		/**
		 * fillColorsを使用するコンポーネントの場合はfillColorsを、それ以外はbackgroundColorを返す
		 **/
		private static function getColorStyleName(comp:UIComponent):String{
			return isFillColorsComponent(comp) ? FILL_COLOR_STYLE_NAME : BG_COLOR_STYLE_NAME;
		}
		/**
		 * DateFieldの場合、中にあるTextInputを返す 
		 */
		private static function stripComponent(comp:UIComponent):UIComponent{
			if(comp is DateField){
				comp = ComboBase(comp).mx_internal::getTextInput();
			}
			return comp;
		}
		/**
		 * fillColorsを使用するコンポーネントかどうか
		 **/
		private static function isFillColorsComponent(comp:UIComponent):Boolean{
			return comp is ComboBox;
		}
		/**
		 * エラー状態のUIComponentを元に戻します。
		 **/
		public static function resetUIError(comp:UIComponent):void{
			comp = stripComponent(comp);
			//元の背景色がある場合、その背景色を取得してセット
			var holdStyle:Object = comp.getStyle(HOLD_BG_COLOR_STYLE_NAME);
			if(holdStyle != null){
				if(holdStyle == NULL_BG_COLOR){
					holdStyle = null;
				}
				var bgStyleName:String = getColorStyleName(comp);
				comp.setStyle(bgStyleName,holdStyle);
			}
			comp.errorString = "";
		}
		/**
		 * 引数のコンテナ以下のUIComponentを検索し、エラー状態を元に戻します。
		 * @param container 対象のコンテナ
		 * @param deepSearch コンテナ内にコンテナがある場合、その中も検索するかどうか　デフォルトtrue
		 **/
		public static function resetChildrenUIError(container:Container,deepSearch:Boolean=true):void{
			var children:Array = container.getChildren();			
			for each(var child:DisplayObject in children){
				if(child is Container && deepSearch){
					resetChildrenUIError(child as Container);
				}else if(child is UIComponent){
					resetUIError(UIComponent(child));
				}
			}
		}
	}
}